package com.song.mall.product.config;

import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.concurrent.Executors;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

/**
 * @author 宋超
 * HP - the login name of the current user.
 * 2021/10/2 - the current system date.
 * 22:09 - the current system time.
 */
//开启指定配置
//@EnableConfigurationProperties(ThreadPoolConfigProperties.class)
@Configuration
public class MyThreadConfig {

    /**
     * 原生线程池的七大参数解释
     *  int corePoolSize, 核心线程数｛只要线程池不销毁，核心线程数一直在｝，线程池创建好以后就准备就绪的线程数量，就等待来接收异步任务去来执行
     *  int maximumPoolSize, 最大线程数，控制资源并发的
     *  long keepAliveTime, 存活时间，如果当前线程数量大于核心数量，只要线程空闲到一定时间内，就会释放空闲的最大线程数当中的线程
     *  TimeUnit unit,  具体最大线程数的存活时间的时间单位
     *  BlockingQueue<Runnable> workQueue, 阻塞队列 如果任务有很多，就会将目前多的任务放在队列里面，只要有空闲的线程，就会去阻塞队列去拿新的任务
     *  ThreadFactory threadFactory,  线程的创建工厂 默认 也可以自定义
     *  RejectedExecutionHandler handler   拒绝策略，就是处理阻塞队列当中任务已满了，不能再加入其他的任务进来阻塞队列当中了，就进行指定的拒绝策略进行拒绝任务
     *
     *  工作顺序：
     * 1. 线程池创建，准备好核心数量的线程，准备接受任务
     * 2. 核心线程数量若满了，就把新进来的任务放到阻塞队列当中，等到核心线程空闲了就去阻塞队列拿新任务并进行执行
     * 3. 如果阻塞队列满了，会开启指定的最大线程数量进行执行阻塞队列当中的任务，并若在指定的时间内最大线程数空闲了，就会释放资源
     * 4.如果阻塞队列和最大现场数量都满了，那么就会使用指定的拒绝策略，来拒绝接受新进来的任务
     *
     *
     * 线程池的其他方法：
     *  Executors.newCachedThreadPool() //核心数是0，所有都可回收
     *         Executors.newFixedThreadPool() //固定大小，核心数=最大值都不可回收
     *         Executors.newScheduledThreadPool() //定时任务的线程池
     *         Executors.newSingleThreadExecutor() //单线程的线程池，后台从队列里面获取任务，挨个执行
     *
     */
    @Bean
    public ThreadPoolExecutor threadPoolExecutor(ThreadPoolConfigProperties pool){
        return new ThreadPoolExecutor(pool.getCoreSize(),pool.getMaxSize(),pool.getKeepAliveTime(), TimeUnit.SECONDS, new LinkedBlockingQueue<>(10000),
                Executors.defaultThreadFactory(),
                new ThreadPoolExecutor.AbortPolicy());
    }
}
